﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CsConsoleImp
{
    internal class Program
    {
        static void Main(string[] args)
        {
             var csvGenerator = new CsvGenerator();
            for (int i = 0; i < CsvGenerator.MAX_CH_NUM; i ++)
            {
                var ret = csvGenerator.Gen(i);
                if (ret == 0)
                {
                    Console.WriteLine("通道{0}处理完毕", i);
                }
                else if (ret == -1)
                {
                    /* do nothing */
                    break;
                }
                else
                {
                    Console.WriteLine("通道{0}数据错误，错误码：{1}", i, ret);
                    break;
                }
            }
            Console.ReadLine();
        }
    }

    class CsvGenerator
    {
        public const int MAX_CH_NUM = 192;
        private const string OUT_PATH = "output";
        private string[][] ch_file;
        public CsvGenerator()
        {
            string path = System.IO.Directory.GetCurrentDirectory();
            ch_file = new string[MAX_CH_NUM][];
            for (int i = 0; i < MAX_CH_NUM; i++)
            {
                string filter_name = "*_ch" + i.ToString() + ".bin";
                ch_file[i] = Directory.GetFiles(path,
                            filter_name, SearchOption.AllDirectories);
                if (ch_file[i] != null && ch_file[i].Length != 0)
                {
                    Array.Sort(ch_file[i]);
                }
            }
            string output_path = path + "\\" + OUT_PATH;
            if (Directory.Exists(output_path))
            {
                Console.WriteLine("删除文件夹：{0}", output_path);
                Directory.Delete(output_path, true);
            }
            if (!Directory.Exists(output_path))
            {
                Directory.CreateDirectory(output_path);
            }
        }

        public int Gen(int ch)
        {
            if (ch >= MAX_CH_NUM || ch_file[ch] == null ||
                ch_file[ch].Length == 0)
            {
                return -1;
            }

            uint index = 0;
            string output_fie = OUT_PATH + "\\" + ch.ToString() + ".csv";
            string fomart = "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}\n";
            string content =
                "序号," +
                "时间戳," +
                "工步号," +
                "运行时间," +
                "状态," +
                "模式," +
                "Flag," +
                "电压," +
                "电流," +
                "容量," +
                "能量," +
                "电池温度\n";
            uint write_linex = 0;

            foreach (var file in ch_file[ch])
            {
                using (FileStream fs = System.IO.File.OpenRead(file))
                {
                    byte[] b = new byte[78];

                    while (true)
                    {
                        int ret = fs.Read(b, 0, b.Length);
                        if (ret == b.Length)
                        {
                            ChRawData raw = new ChRawData(b);
                            DateTime startTime =
                                TimeZone.CurrentTimeZone.ToLocalTime(
                                    new DateTime(1970, 1, 1));
                            DateTime now_time = startTime.AddSeconds(raw.timestamp_s);
                            ++index;
                            content += String.Format(fomart,
                                            index,
                                            now_time,
                                            raw.step_index,
                                            raw.run_time,
                                            raw.status,
                                            raw.mode,
                                            raw.flag,
                                            raw.voltage,
                                            raw.current,
                                            raw.capacity,
                                            raw.power,
                                            raw.bat_temp);
                            ++write_linex;
                            if (write_linex >= 128)
                            {
                                File.AppendAllText(output_fie, content, UnicodeEncoding.UTF8);
                                write_linex = 0;
                                content = null;
                            }
                        }
                        else if (ret > 0)
                        {
                            Console.WriteLine("警告：数据文件有错误: {0}！！！", file);
                            return -2;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            return 0;
        }
    }
    public class ChRawData
    {
        public uint timestamp_s;
        public uint timestamp_us;
        public ushort step_index;
        public ushort process_cycle;
        public ushort step_cycle;
        public uint run_time;
        public byte status;
        public byte mode;
        public byte flag;
        public byte ign_status;
        public float voltage;
        public float current;
        public float capacity;
        public float power;
        public float bat_temp;
        public float dcr;
        public float probe_voltage;
        public float dcir;
        public float line_voltage;
        public float reserve0;
        public float reserve1;
        public float reserve2;
        public float reserve3;
        public float reserve4;

        public ChRawData(byte[] datas)
        {
            MemoryStream ms = new MemoryStream(datas, 0, datas.Length);
            BinaryReader br = new BinaryReader(ms);
            timestamp_s = br.ReadUInt32();
            timestamp_us = br.ReadUInt32();
            step_index = br.ReadUInt16();
            process_cycle = br.ReadUInt16();
            step_cycle = br.ReadUInt16();
            run_time = br.ReadUInt32();
            status = br.ReadByte();
            mode = br.ReadByte();
            flag = br.ReadByte();
            ign_status = br.ReadByte();
            voltage = br.ReadSingle();
            current = br.ReadSingle();
            capacity = br.ReadSingle();
            power = br.ReadSingle();
            bat_temp = br.ReadSingle();
            dcr = br.ReadSingle();
            probe_voltage = br.ReadSingle();
            dcir = br.ReadSingle();
            line_voltage = br.ReadSingle();
            reserve0 = br.ReadSingle();
            reserve1 = br.ReadSingle();
            reserve2 = br.ReadSingle();
            reserve3 = br.ReadSingle();
            reserve4 = br.ReadSingle();
        }
    }
}
